/**
 * @desc 获取图片地址的公有方法,静态图片放在插件中会被智联等网站拦截，因此全部放在主站的keep目录下
 * @param image [sting] {images/logo.png} 图片地址
 *
 */
var keepUtil = {
  getImageUrl (image) {
    return 'https://stnew03.beisen.com/ux/tms-recruit/release/app/extras/keep/' + image
  }
}

/**
 * 渡江8期
 * 封装一个localStorage的crud操作，实在受不了之前实现了，每增加一个缓存的类型，就得老逻辑拷贝一份然后在其基础上改
 */
var StorageCRUD = {
  update ({ namespace = '', data = '' }) {
    // data: object | array
    // key: string
    try {
      let cache = StorageCRUD.retrieve(namespace)
      if (!cache) {
        StorageCRUD.create({ namespace, data })
      }
      if (typeof (cache) === 'string') {
        // 如果是需要更新的目标缓存是字符串则直接更新
        localStorage.setItem(namespace, data)
        return
      }
      localStorage.setItem(namespace, JSON.stringify(data))
    } catch (e) {
      console.error('Storage.update error: ', e)
    }
  },
  delete ({ namespace = '', data = '', key = '' }) {
    // 1. 支持删除整个缓存命名空间
    // 2. 支持删除数组缓存中的某个值，只支持能用全等匹配的值，如果是删除对象数组中的值，请用update手动实现
    // 3. 支持删除对象缓存中的某个属性
    try {
      // 支持功能1
      if (!key && !data) {
        localStorage.removeItem(namespace)
        return
      }

      let cache = StorageCRUD.retrieve(namespace)
      // 支持功能2
      if (Array.isArray(cache)) {
        cache = cache.filter(item => item != data)
      } else {
        // 支持功能3
        if (!key) throw 'key 为空，delete失败'
        delete cache[key]
      }
      StorageCRUD.update({ namespace, data: cache })
    } catch (e) {
      console.error('Storage.delete error: ', e)
    }
  },
  create ({ namespace = '', data = '' }) {
    try {
      if (typeof (data) === 'string') {
        localStorage.setItem(namespace, data)
      }
      localStorage.setItem(namespace, JSON.stringify(data))
    } catch (e) {
      console.error('StorageCRUD.update error: ', e)
    }
  },
  // 检索（读取查询）
  retrieve (namespace) {
    let cache
    try {
      if (!namespace) return null
      cache = localStorage.getItem(namespace)
      return JSON.parse(cache)
    } catch (e) {
      // cache为纯不规则的字符串, 或者为空
      console.warn('StorageCRUD.query cache直出: ', e)
      console.log('catch cache: ', cache)
      return cache
    }
  },
  // 扩展一个插入操作
  insert ({ namespace = '', data, key = '' }) {
    // 只针对数组和对象进行插入操作
    let cache = StorageCRUD.retrieve(namespace)
    console.log('%cStorageCRUD insert: ', 'color: blue', cache, namespace, data, key)
    if (!cache) {
      // 如果没有缓存，则直接创建，创建数组还是对象根据有无key来区分
      cache = key ? { [key]: data } : [data]
      StorageCRUD.create({ namespace, data: cache })
      return
    }

    if (Array.isArray(cache)) {
      cache.push(data)
    }

    if (Object.prototype.toString.call(cache) === '[object Object]') {
      if (!key) return
      cache[key] = data
    }
    StorageCRUD.update({ namespace, data: cache })
  }
}

chrome.runtime.getStorageLocalPromise = keys => new Promise((resolve, reject) => {
  chrome.storage.local.get(keys, (data) => {
    if (chrome.runtime.lastError) {
      return reject(chrome.runtime.lastError)
    }
    resolve(data)
  })
})
chrome.runtime.setStorageLocalPromise = obj => new Promise((reject, resolve) => {
  chrome.storage.local.set(obj, () => {
    if (chrome.runtime.lastError) return reject(chrome.runtime.lastError)
    resolve(true)
  })
})
chrome.runtime.removeStorageLocalPromise = keys => new Promise((resolve, reject) => {
  chrome.storage.local.remove(keys, () => {
    if (chrome.runtime.lastError) return reject(chrome.runtime.lastError)
    resolve(true)
  })
})

/**
 * 队列
 */

let Queue = (function() {
  const items = new WeakMap()
  class Queue {
    constructor(data = []) {
      items.set(this, data)
    }
    enqueue(el) {
      let q = items.get(this)
      q.push(el)
    }
    dequeue() {
      let q = items.get(this)
      let r = q.shift()
      return r
    }
    isEmpty() {
      let q = items.get(this)
      return q.length === 0
    }
    size() {
      let q = items.get(this)
      return q.length
    }
    front() {
      let q = items.get(this)
      return q[0]
    }
    getAll() {
      let q = items.get(this)
      return q
    }
  }
  return Queue
})()